package com.wdl.modules.myhouse.security.filter;

import com.auth0.jwt.exceptions.JWTDecodeException;
import com.wdl.modules.myhouse.exception.VerifiCodeException;
import com.wdl.modules.myhouse.security.entity.UserInfo;
import com.wdl.modules.myhouse.security.deprecated.mailLogin.MailLoginToken;
import com.wdl.modules.myhouse.service.UserService;
import com.wdl.modules.myhouse.utils.util.JWTUtils;
import com.wdl.modules.myhouse.utils.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author 昏昏的君
 */
@Component

public class MailLoginFilter extends OncePerRequestFilter {

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private UserService userService;
    @Autowired
    private AuthenticationSuccessHandler successHandler;


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String mailLogin = request.getParameter("ISMAIL");
        if ("/login".equals(request.getRequestURI()) && request.getMethod().equalsIgnoreCase("POST")
                && mailLogin!=null && !mailLogin.isEmpty()
        ) {
            try {
                //邮箱登录逻辑
                String code = request.getParameter("code");
                //这里字段名是username，但是保存的是邮箱信息
                String username = request.getParameter("username");
                //验证邮箱登录
                String prentedCode = null;
                try {
                    String token = redisUtil.getValue(username);
                    prentedCode = JWTUtils.getToken(token).getClaim("CODE").asString();
                } catch (JWTDecodeException e) {
                    request.setAttribute("LOGINException", new VerifiCodeException("邮箱验证码有误,JWT解析异常"));
                    throw new VerifiCodeException("邮箱验证码有误,JWT解析异常");
                } catch (NullPointerException e) {
                    request.setAttribute("LOGINException", new VerifiCodeException("不存在当前邮箱的验证码记录,验证码或已过期"));
                    throw new VerifiCodeException("不存在当前邮箱的验证码记录,验证码或已过期");
                }
                if (prentedCode == null || !prentedCode.equals(code)) {
                    request.setAttribute("LOGINException", new VerifiCodeException("验证码不正确"));
                    throw new VerifiCodeException("验证码不正确");
                }
                // 验证通过，删除当前验证码信息
                redisUtil.delVal(username);
                //保存用户信息到springSecurity
                UserInfo userInfo = userService.getUserInfoByMail(username);
                MailLoginToken loginToken = null;
                if (userInfo != null) {
                    loginToken = new MailLoginToken(userInfo, userInfo.getPassword(), userInfo.getAuthorities());
                    loginToken.setDetails(request);
                    SecurityContextHolder.getContext().setAuthentication(loginToken);
                } else {
                    throw new VerifiCodeException("找不到当前邮箱的用户信息");
                }
                successHandler.onAuthenticationSuccess(request, response, loginToken);
            } catch (VerifiCodeException e) {
                filterChain.doFilter(request, response);
            }
        } else {
            filterChain.doFilter(request, response);
        }
    }
}

